//
//  AEUIManager.h
//  GameJam-Mac
//
//  Created by Clover Sin on 12/26/11.
//  Copyright (c) 2011 Snow Poem Society. All rights reserved.
//

#ifndef GameJam_Mac_AEUIManager_h
#define GameJam_Mac_AEUIManager_h

#include "stdafx.h"
#include "AEControl.h"
#include "AETheme.h"
#include "AEUtility.h"

#include "AEButton.h"


/** 
 * AEUIManager is the core object which 
 *  handles all the events from user input 
 *  and controls. 
 */
#define theUIManager AEUIManager::getIntance()

class AEUIManager : protected MessageListener, 
                    protected MouseListener, 
                    protected Renderable 
{
    // Declare they are friend, so they are able to 
    //   invoke callbacks.
    friend class World;
    friend class Switchboard;
    
public:
    
    static AEUIManager& getIntance()
    {
        if (s_AEUIManager == NULL)
        {
            s_AEUIManager = new AEUIManager();
        }
        return *s_AEUIManager;
    }
    
    AETheme* getCurrentTheme() { return _currentTheme; }
    
    AEControl* getRootControl() { return _rootControl; }
    
    // TODO: implement the 3 method. 
    bool isControlsEnable() { return true; }
    void enableControls() {}
    void disableControls() {}
    
    // Apply monopolizing mouse and keyboard event.
    void applyMonopolize(AEControl* apply) {}
    // Apply not monopolizing any more.
    void applyEndMonopolize(AEControl* apply) {}
    
    // TODO: Put factory methods here, with the syntax of: 
    //   add + __ControlName__ + (Vec2i coor, args...)
    AEButton* addButton(Vector2 coor, AEDelegate d = AEDelegate());
    AELabel* addLabel(Vector2 coor, const String& text);
    
protected:
    
    AEUIManager();
    virtual ~AEUIManager();
    
    // TODO: Initialize theme from config file or code.
    void setTheme(AETheme* theme);
    
    // Get input from message, except mouse events. 
    void ReceiveMessage(Message* message);
    
    // Mouse events handle methods.
    void MouseMotionEvent(Vec2i coor);
    void MouseDownEvent(Vec2i coor, MouseButtonInput button);
    void MouseUpEvent(Vec2i coor, MouseButtonInput button);
    void MouseWheelEvent(int position);
    
    // Update every frame.
    void Update(float dt);
    
    static AEUIManager* s_AEUIManager;
    
private:
    
    bool _enabled;
    
    // TODO: Make themes changable. 
    AETheme* _currentTheme;
    
    // Root control node.
    AEControl* _rootControl;
    
    // Last used control.
    AEControl* _activeControl;
    
    // If any control is handling, ignore the others.
    // NULL if no controls is handling.
    AEControl* _controlWhoIsHandling;
    
    // The control which touched the FRAME BEFORE CURRENT FRAME.
    // That is, this will only reference the control touched 
    //   a frame before, if no control touched a frame before, 
    //   the value will be NULL.
    AEControl* _controlTouchedAFrameBefore;
    
    // Store the current mouse position as Vector2, instead of
    //  a Vec2i.
    Vector2 _mousePosition;
};

#endif
